package Modele;

import java.util.ArrayList;
import java.util.Calendar;

import Helpers.Configuration;


public class Billet extends Model
{
	private StatusBillet status;
	private Representation representation;
	private Calendar dateLiberation;
	
	public enum StatusBillet
	{
		DISPONIBLE,
		RESERVE,
		ACHETE
	}		

	public  Billet (Representation representation)
	{
		this.representation = representation;
		this.status = StatusBillet.DISPONIBLE;
		this.dateLiberation = Calendar.getInstance();
	}
	
	public synchronized void reserver ( ) throws Exception
	{
		if ( ! estReserve ( ) )
		{
			this.status = StatusBillet.RESERVE;
			this.dateLiberation = Calendar.getInstance();
			this.dateLiberation.add( Calendar.MINUTE, Configuration.TIMEOUT_BILLETS );
			notifyReservationEffectuee();
		}
		else
		{
			throw new Exception ( "Ce billet est déjà réservé!" );
		}
	}
		
	public void liberer ( )
	{
		notifyReservationLiberee();
		this.status = StatusBillet.DISPONIBLE;		
	}
	
	public void acheter ( )
	{
		this.status = StatusBillet.ACHETE;
		notifyAchatEffectue();
	}
	
	public boolean estDisponible ( )
	{
		if ( reservationExpiree ( ) && this.status == StatusBillet.RESERVE )
			liberer ( );
			
		return ( this.status == StatusBillet.DISPONIBLE );
	}
	
	public boolean reservationExpiree ( )
	{
		return this.dateLiberation.before(Calendar.getInstance());
	}
	
	public boolean estReserve ( )
	{
		return ( this.status == StatusBillet.RESERVE );
	}
	
	public StatusBillet getStatus ( )
	{
		if ( reservationExpiree ( ) && this.status == StatusBillet.RESERVE )
			liberer ( );
		
		return this.status;
	}
	
	public Representation getRepresentation()
	{
		return this.representation;
	}
	
	
	
	private ArrayList<BilletListener> listeners = new ArrayList<BilletListener> ();
	
	public void addListener ( BilletListener l )
	{
		listeners.add( l );
	}
	
	private void notifyReservationEffectuee ( )
	{
		for ( BilletListener l : listeners )
			try
			{
				l.reservationEffectuee(this);
			}
			catch ( Exception e ){}
	}
	
	private void notifyReservationLiberee ( )
	{
		for ( BilletListener l : listeners )
			try
			{
				l.reservationLiberee(this);
			}
			catch ( Exception e ) {}
	}	
	
	private void notifyAchatEffectue ( )
	{
		for ( BilletListener l : listeners )
			try
			{
				l.achatEffectue(this);
			}
			catch ( Exception e ){}
	}
	
	public interface BilletListener
	{
		public void reservationEffectuee ( Billet b );
		public void reservationLiberee ( Billet b );
		public void achatEffectue ( Billet b );
	}
}
